package com.xiaowanzi.transporter.decoder;

import com.xiaowanzi.transporter.constants.Constants;
import com.xiaowanzi.transporter.constants.MessageTypeEnum;
import com.xiaowanzi.transporter.model.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.nio.charset.Charset;
import java.util.List;

public class MessageDecoder extends ByteToMessageDecoder {

  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
    Message message = new Message();
    message.setMagicNumber(byteBuf.readInt());  // magicNumber
    message.setMainVersion(byteBuf.readByte()); // mainVersion
    message.setSubVersion(byteBuf.readByte()); // subVersion
    message.setModifyVersion(byteBuf.readByte());
    CharSequence sessionId = byteBuf.readCharSequence(
        Constants.SESSION_ID_LENGTH, Charset.defaultCharset());
    message.setSessionId((String)sessionId);

    message.setMessageType(MessageTypeEnum.get(byteBuf.readByte()));
    short attachmentSize = byteBuf.readShort();
    for (short i = 0; i < attachmentSize; i++) {
      int keyLength = byteBuf.readInt();
      CharSequence key = byteBuf.readCharSequence(keyLength, Charset.defaultCharset());
      int valueLength = byteBuf.readInt();
      CharSequence value = byteBuf.readCharSequence(valueLength, Charset.defaultCharset());
      message.addAttachment(key.toString(), value.toString());
    }

    int bodyLength = byteBuf.readInt();
    CharSequence body = byteBuf.readCharSequence(bodyLength, Charset.defaultCharset());
    message.setBody(body.toString());
    out.add(message);
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    cause.printStackTrace();
  }
}
